<template>
  <el-dialog v-model="isDialogVisible" @open="openDialog" @close="closeDialog" :style="{ height: props.dialogConfig.dialogHeight, width: props.dialogConfig.dialogWidth }">
    <template #header>
      <!-- 自定义标题 -->
      <slot name="header">标题</slot>
    </template>
    <el-tabs :type="tabsType" v-model="currentTab" :before-leave="resetFieldInfo" style="width: 100%">
      <!-- 切换选项卡 -->
      <el-tab-pane v-for="tab in props.tabs" :key="tab.label" :name="tab.label">
        <!-- 选项卡名称 -->
        <template #label>
          <span :style="{ fontSize: props.dialogConfig.tabSize }">{{ tab.label }}</span>
        </template>
        <!-- 选项卡具体页面 -->
        <div class="dialog-main">
          <el-form :ref="setFormRef(tab.label)" :model="localFieldInfo" :rules="props.rules" label-width="80px">
            <div v-for="field in tab.fieldConfig" :key="field.prop">
              <!-- 文本框部分 -->
              <el-form-item :label="field.label" :prop="field.prop">
                <template v-if="field.type === 'input'">
                  <el-input
                    v-model="localFieldInfo[field.prop]"
                    :placeholder="field.placeholder"
                    :readonly="field.readonly"
                    :disabled="field.disabled"
                    :show-password="field.isPassword"
                    :style="{ width: field.width || '70%' }"
                  />
                  <!-- 输入框后的按钮 -->
                  <slot :name="'append-' + field.prop" v-if="field.showAppendSlot"></slot>
                </template>
                <!-- 下拉框部分 -->
                <template v-else-if="field.type === 'select'">
                  <el-select v-model="localFieldInfo[field.prop]" :placeholder="field.placeholder" :readonly="field.readonly" :disabled="field.disabled" :style="{ width: field.width || '70%' }">
                    <el-option v-for="option in field.options" :key="option.value" :label="option.label" :value="option.value" />
                  </el-select>
                </template>
                <!-- 复选框部分 -->
                <template v-else-if="field.type === 'checkbox'">
                  <el-checkbox-group v-model="localFieldInfo[field.prop]">
                    <el-checkbox v-for="checkbox in field.checkboxes" :key="checkbox.label" :label="checkbox.label" />
                  </el-checkbox-group>
                </template>
                <!-- 单选框部分 -->
                <template v-else-if="field.type === 'radio'">
                  <el-radio-group v-model="localFieldInfo[field.prop]">
                    <el-radio v-for="radio in field.radios" :key="radio.label" :label="radio.label" />
                  </el-radio-group>
                </template>
              </el-form-item>
            </div>
          </el-form>
        </div>
      </el-tab-pane>
    </el-tabs>
    <template #footer>
      <!-- 自定义页脚(已将表单信息和关闭弹窗函数暴露) -->
      <slot name="footer">
        <el-button @click="submitForm">提交</el-button>
        <el-button @click="closeDialog">关闭</el-button>
      </slot>
    </template>
  </el-dialog>
</template>

<script setup>
import { ref } from 'vue'
import { useCounterStore } from '@/stores/counter.js'
/* defineProps 父传子 */
const props = defineProps({
  // dialog配置
  dialogConfig: {
    type: Object,
    default: () => ({
      dialogHeight: '600px',
      dialogWidth: '400px',
      tabSize: '16px'
    })
  },
  // tabs类型
  tabsType: {
    type: String,
    required: false,
    default: ''
  },
  // 选项卡配置
  tabs: {
    type: Array,
    default: () => [
      { label: '用户管理', fieldConfig: [{ type: 'input', prop: 'idCard', label: '用户名', isPassword: false, showAppendSlot: true }] },
      {
        label: '配置管理',
        fieldConfig: [
          { type: 'input', prop: 'personName', label: '用户名2', width: '60%' },
          {
            type: 'select',
            prop: 'typeName',
            label: '性别',
            options: [
              { label: '男', value: '男' },
              { label: '女', value: '女' }
            ]
          },
          {
            type: 'checkbox',
            prop: 'checkbox',
            label: '复选框',
            checkboxes: [{ label: '选项1' }, { label: '选项2' }]
          },
          {
            type: 'radio',
            prop: 'radio',
            label: '单选框',
            radios: [{ label: '选项1' }, { label: '选项2' }]
          }
        ]
      }
    ]
  },
  // 默认信息项，根据prop字段名填写
  fieldInfo: {
    type: Object,
    default: () => ({ idCard: '5105', personName: 'test', typeName: '男', checkbox: ['选项1'], radio: '选项1' })
  },
  // 自定义规则
  rules: {
    type: Object,
    required: false,
    default: () => ({
      idCard: [{ required: true, message: '需要填写该项', trigger: 'blur' }],
      personName: [{ required: true, message: '需要填写该项', trigger: 'blur' }],
      typeName: [{ required: true, message: '需要填写该项', trigger: 'blur' }]
    })
  }
})

/* 本界面变量或方法 */
const localFieldInfo = ref({ ...props.fieldInfo }) // 包装fieldInfo使其成为响应式对象
const currentTab = ref(props.tabs[0].label) // 当前选项卡标识符
const formRefs = ref({}) // 表单引用存储
const isDialogVisible = ref(false) // 弹窗是否显示
const counterStore = useCounterStore() // 从stores中创建实例
// 获得ref响应对象
const setFormRef = (label) => (el) => {
  formRefs.value[label] = el
}

/* defineExpose 子传父的方法 */
// 提交表单数据
const submitForm = async () => {
  try {
    const currentForm = formRefs.value[currentTab.value] // 获取当前的表单ref
    // 使用封装的方法进行表单验证
    await counterStore.validateForm(currentForm)
    // 查找当前选项卡的配置
    const currentTabConfig = props.tabs.find((tab) => tab.label === currentTab.value)
    if (!currentTabConfig) {
      console.log('未找到当前选项卡配置')
      return
    }
    // 构建提交的表单数据对象，只包含当前选项卡相关的字段
    const formData = {}
    currentTabConfig.fieldConfig.forEach((field) => {
      formData[field.prop] = localFieldInfo.value[field.prop]
    })
    return formData
  } catch (error) {
    // 处理表单验证失败的逻辑
    // console.error(error.message)
    return
  }
}
// 初始化表单
const resetFieldInfo = () => {
  const currentForm = formRefs.value[currentTab.value] // 获取当前的表单ref
  currentForm.resetFields() // 将表单恢复成初始状态
}
// 开启/关闭弹窗
const openDialog = () => {
  isDialogVisible.value = true
}
const closeDialog = () => {
  isDialogVisible.value = false
  currentTab.value = props.tabs[0].label // 重置选项卡为第一项
  resetFieldInfo() // 重置字段数据
}
defineExpose({
  submitForm,
  openDialog,
  closeDialog,
  resetFieldInfo
})
</script>

<style lang="scss" scoped>
:deep(.el-dialog__body) {
  padding: 2px !important;
}
</style>
